﻿using System.Linq.Expressions;
using Furion;
using HiSport.Core;
using HiSportApplet.Core;
using HiSportApplet.Core.Const;
using SqlSugar;

namespace HiSportApplet.Application.Common.SqlSugar
{
    /// <summary>
    /// SqlSugar 实体仓储
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SqlSugarRepository<T> : SimpleClient<T>, ISqlSugarRepository<T> where T : class, new()
    {
        protected ITenant iTenant = null;

        public SqlSugarRepository(ISqlSugarClient context = null) : base(context)
        {
            iTenant = App.GetRequiredService<ISqlSugarClient>().AsTenant();
            if (typeof(T).IsDefined(typeof(TenantAttribute), false))
            {
                base.Context = iTenant.GetConnectionScopeWithAttr<T>();
                return;
            }
            if (typeof(T).IsDefined(typeof(LogTableAttribute), false))
            {
                base.Context = iTenant.IsAnyConnection(SqlSugarConst.ConfigId)
                    ? iTenant.GetConnectionScope(SqlSugarConst.ConfigId)
                    : iTenant.GetConnectionScope(SqlSugarConst.BaseConfigId);
                return;
            }
            if (typeof(T).IsDefined(typeof(SysTableAttribute), false))
            {
                base.Context = iTenant.GetConnectionScope(SqlSugarConst.BaseConfigId);
                return;
            }

            var tenantId = 0;
            if (tenantId < 1 || tenantId.ToString() == SqlSugarConst.BaseConfigId) return;
            base.Context = iTenant.GetConnectionScope(tenantId.ToString());
        }

        #region 分表操作

        public async Task<bool> SplitTableInsertAsync(T input)
        {
            return await base.AsInsertable(input).SplitTable().ExecuteCommandAsync() > 0;
        }

        public async Task<bool> SplitTableInsertAsync(List<T> input)
        {
            return await base.AsInsertable(input).SplitTable().ExecuteCommandAsync() > 0;
        }

        public async Task<bool> SplitTableUpdateAsync(T input)
        {
            return await base.AsUpdateable(input).SplitTable().ExecuteCommandAsync() > 0;
        }

        public async Task<bool> SplitTableUpdateAsync(List<T> input)
        {
            return await base.AsUpdateable(input).SplitTable().ExecuteCommandAsync() > 0;
        }

        public async Task<bool> SplitTableDeleteableAsync(T input)
        {
            return await base.Context.Deleteable(input).SplitTable().ExecuteCommandAsync() > 0;
        }

        public async Task<bool> SplitTableDeleteableAsync(List<T> input)
        {
            return await base.Context.Deleteable(input).SplitTable().ExecuteCommandAsync() > 0;
        }

        public Task<T> SplitTableGetFirstAsync(Expression<Func<T, bool>> whereExpression)
        {
            return base.AsQueryable().SplitTable().FirstAsync(whereExpression);
        }

        public Task<bool> SplitTableIsAnyAsync(Expression<Func<T, bool>> whereExpression)
        {
            return base.Context.Queryable<T>().Where(whereExpression).SplitTable().AnyAsync();
        }

        public Task<List<T>> SplitTableGetListAsync()
        {
            return Context.Queryable<T>().SplitTable().ToListAsync();
        }

        public Task<List<T>> SplitTableGetListAsync(Expression<Func<T, bool>> whereExpression)
        {
            return Context.Queryable<T>().Where(whereExpression).SplitTable().ToListAsync();
        }

        public Task<List<T>> SplitTableGetListAsync(Expression<Func<T, bool>> whereExpression, string[] tableNames)
        {
            return Context.Queryable<T>().Where(whereExpression).SplitTable(t => t.InTableNames(tableNames)).ToListAsync();
        }

        #endregion 分表操作
    }
}
